using System.Web.Mvc;
using Rhino.Commons;
using Rhino.Security.Interfaces;
using WineCellar.Business.ServiceInterfaces;

namespace WineCellar.Web.Security
{
    public class AuthorizationAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Authenticated?

            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {               
                filterContext.Result = new HttpUnauthorizedResult();
                return;
            }

            // Authorized?

            var user = IoC.Resolve<IUserService>().GetUser(filterContext.HttpContext.User.Identity.Name);
            var actionName = filterContext.RouteData.Values["action"];            

            var operation = string.Format("/{0}/{1}", filterContext.Controller.GetType().BaseType.Name, actionName);

            var authorizationService = IoC.Resolve<IAuthorizationService>();

            if (!authorizationService.IsAllowed(user, operation))
            {
                //check whether the user is authorized to perform the action on the inherited type of the controller
                operation = string.Format("/{0}/{1}", filterContext.Controller.GetType().BaseType.BaseType.Name, actionName);
                if (!authorizationService.IsAllowed(user, operation))
                {
                    //check whether we are dealing with a generic type
                    if (filterContext.Controller.GetType().BaseType.BaseType.IsGenericType)
                    {
                        operation = string.Format("/{0}/{1}", filterContext.Controller.GetType().BaseType.BaseType.Name.Substring(0, filterContext.Controller.GetType().BaseType.BaseType.Name.Length -2), actionName);
                        if (!authorizationService.IsAllowed(user, operation))
                        {
                            filterContext.Controller.TempData["ErrorMessage"] = string.Format("You are not authorized to perform operation: {0}", operation);
                            filterContext.Result = new HttpUnauthorizedResult();          
                        }
                    }                    
                }                
            }
        }
    }
}